#pragma once
#include <vector>
#include <mutex>
#include <chrono>
#include <algorithm>
#include <unordered_map>
#include <atomic>
#include <thread>
#include <iostream>
class ClientManager {

  public:
    ClientManager()                      = default;
    ~ClientManager()                     = default;
    ClientManager(const ClientManager &) = delete;
    ClientManager(int connection_timeout) : _connection_timeout(connection_timeout) {}

    void add_client(int fd) {
        std::lock_guard<std::mutex> lock(_client_mutex);
        if (_clients.count(fd) == 0) {
            _clients[fd] = std::chrono::steady_clock::now();
        } else {
            std::cerr << "Client :" << fd << " already exists" << std::endl;
        }
    };

    void remove_client(int fd) {
        std::lock_guard<std::mutex> lock(_client_mutex);
        if (_clients.count(fd) > 0) {
            _clients.erase(fd);
        } else {
            std::cerr << "Client :" << fd << " does not exist" << std::endl;
        }
    };

    void remove_client(std::vector<int> fds) {
        std::lock_guard<std::mutex> lock(_client_mutex);
        for (int fd : fds) {
            _clients.erase(fd);
        }
    }
    std::vector<int> remove_inactive_clients(std::chrono::steady_clock::time_point now) {
        std::lock_guard<std::mutex> lock(_client_mutex);
        std::vector<int> inactive_clients;
        for (auto it = _clients.begin(); it != _clients.end();) {
            if (now - it->second > std::chrono::seconds(_connection_timeout)) {
                inactive_clients.push_back(it->first);
                it = _clients.erase(it);
            } else {
                ++it;
            }
        }
        return inactive_clients;
    };
    void update_client_activity(int fd) {
        std::lock_guard<std::mutex> lock(_client_mutex);
        if (_clients.count(fd) > 0) {
            _clients[fd] = std::chrono::steady_clock::now();
        } else {
            std::cerr << "Client :" << fd << " does not exist" << std::endl;
        }
    }
    std::vector<int> get_all_clients() {
        std::lock_guard<std::mutex> lock(_client_mutex);
        std::vector<int> active_clients;
        for (const auto &pair : _clients) {
            active_clients.push_back(pair.first);
        }
        return active_clients;
    }
    void set_connection_timeout(int timeout) {
        std::lock_guard<std::mutex> lock(_client_mutex);
        _connection_timeout = timeout;
    }

  private:
    std::unordered_map<int, std::chrono::steady_clock::time_point> _clients;
    std::mutex _client_mutex;
    int _connection_timeout = 15; // 15秒未活动则断开连接
};

struct ServerState {
    int server_fd             = -1;
    int epoll_fd              = -1;
    std::atomic<bool> running = true;
    std::thread hb_thread;
};
